package core;

import graphics.GuitarKeys;

import java.awt.Color;
import java.util.List;

import javax.media.opengl.GL;

import music.Note;
import music.Song;

import com.sun.opengl.util.GLUT;

public class Player {
	static int noOfPlayers;
	int playerNumber;
	private GuitarKeys guitarKeys;
	private float offsetX = 0.0f;
	private float rotationY = 1.0f;
	private Color keyColors[];
	private Color defaultKeyColor = new Color(50, 200, 50);

	public float getRotationY() {
		return rotationY;
	}

	public void setRotationY(float rotationY) {
		this.rotationY = rotationY;
	}

	private Song song;
	Color released = new Color(0.5f, 0.5f, 0.5f);
	Color pressed = new Color(0.5f, 1.0f, 0.5f);
	int notesHit = 0;
	GLUT glut;

	public Player(GuitarKeys guitarKeys) {
		this.guitarKeys = guitarKeys;
		keyColors = new Color[guitarKeys.getNoOfKeys()];
		playerNumber = noOfPlayers++;
		glut = new GLUT();
	}

	public void setOffsetX(float x) {
		offsetX = x;
	}

	public float getOffsetX() {
		return offsetX;
	}

	public void display(GL gl) {
		// System.out.println(song.getTime());
		gl.glTranslatef(-offsetX, 0.0f, 0.0f);
		gl.glRotatef(rotationY, 0.0f, 1.0f, 0.0f);
		displayBar(gl);
		if (song != null)
			displayNotes(gl);
		displayKeys(gl);
		displayStats(gl);
		gl.glRotatef(-rotationY, 0.0f, 1.0f, 0.0f);
		gl.glTranslatef(offsetX, 0.0f, 0.0f);
	}

	private void displayStats(GL gl) {
		gl.glRasterPos2i(1, 1);
		glut.glutBitmapString(GLUT.BITMAP_TIMES_ROMAN_24, "Hit: " + notesHit);

	}

	private void displayBar(GL gl) {
		gl.glColor3f(0.0f, 1.0f, 0.0f);
		gl.glPushMatrix();
		float lineWidth = 0.05f / 2;
		for (int line = 0; line < 5; line++) {
			float x = -line / 5f;
			gl.glBegin(GL.GL_POLYGON);
			gl.glVertex3f(x - lineWidth, 0, 0);
			gl.glVertex3f(x + lineWidth, 0, 0);
			gl.glVertex3f(x - lineWidth, 0, 400);
			gl.glVertex3f(x + lineWidth, 0, 400);
			gl.glEnd();
		}
		// XeroBar
		gl.glBegin(GL.GL_POLYGON);
		gl.glVertex3f(0.1f, 0, lineWidth);
		gl.glVertex3f(0.1f, 0, -lineWidth);
		gl.glVertex3f(-0.9f, 0, -lineWidth);
		gl.glVertex3f(-0.9f, 0, lineWidth);
		gl.glEnd();

	}

	private void displayKey(GL gl, float x, float y, float z, Color color) {

		gl.glColor3fv(color.getColorComponents(null), 0);
		gl.glBegin(GL.GL_POLYGON);
		gl.glVertex3f(x - 0.071f, y - 0.0f, z);
		gl.glVertex3f(x + 0.071f, y - 0.0f, z);
		gl.glVertex3f(x + 0.1f, y - 0.0f, z + 0.1f);
		gl.glVertex3f(x + 0.071f, y + 0.0f, z + 0.2f);
		gl.glVertex3f(x - 0.071f, y + 0.0f, z + 0.2f);
		gl.glVertex3f(x - 0.1f, y + 0.0f, z + 0.1f);
		gl.glEnd();
	}

	private void displayKeys(GL gl) {
		for (int i = 0; i < guitarKeys.getNoOfKeys(); i++) {
			float offsetX = i / 5f;
			if (guitarKeys.getKey(i))
				displayKey(gl, -offsetX, 0.01f, -0.50f, getKeyColor(i)
						.brighter());
			else
				displayKey(gl, -offsetX, 0.01f, -0.50f, getKeyColor(i).darker());
		}
	}

	private Color getKeyColor(int i) {
		if (keyColors[i] != null)
			return keyColors[i];
		return defaultKeyColor;

	}

	public void setKeyColors(Color colors[]) {
		for (int i = 0; i < colors.length; i++) {
			keyColors[i] = colors[i];
		}

	}

	private void displayNote(GL gl, float x, float y, float z, Color c) {
		gl.glColor3fv(c.getColorComponents(null), 0);
		gl.glBegin(GL.GL_POLYGON);
		gl.glVertex3f(x - 0.071f, y - 0.0f, z);
		gl.glVertex3f(x + 0.071f, y - 0.0f, z);
		gl.glVertex3f(x + 0.1f, y - 0.0f, z + 0.1f);
		gl.glVertex3f(x + 0.071f, y + 0.0f, z + 0.2f);
		gl.glVertex3f(x - 0.071f, y + 0.0f, z + 0.2f);
		gl.glVertex3f(x - 0.1f, y + 0.0f, z + 0.1f);
		gl.glEnd();
	}

	private void displayNotes(GL gl) {
		List<Note> notes = song.getNotes();
		Note note;
		if (song != null) {
			int startNote = song.getNextNoteNumber();
			int endNote = startNote + 30;
			if (endNote > notes.size())
				endNote = notes.size();
			for (int i = song.getNextNoteNumber(); i < endNote; i++) {
				note = notes.get(i);
				float noteOffsetZ = (float) (2.0f * (note.getTime() - song
						.getTime()) / 1000.0f);
				if (note.isHit())
					gl.glColor3f(0.0f, 1.0f, 1.0f);
				else if (note.isMissed())
					gl.glColor3f(1.0f, 0.0f, 0.0f);
				else
					gl.glColor3f(1.0f, 1.0f, 0.0f);
				for (int j = 0; j < 5; j++) {
					if (note.isSet(j)) {
						float noteOffsetX = j / 5f;
						displayNote(gl, -noteOffsetX, 0.01f, noteOffsetZ, getKeyColor(i));
					}
				}
			}
		}
	}

	public GuitarKeys getGuitarKeys() {
		return guitarKeys;
	}

	public Song getSong() {
		return song;
	}

	public void hit() {
		if (song.hit(playerNumber, guitarKeys)) {
			notesHit++;
			song.unMuteGuitar(playerNumber);
		} else {
			notesHit = 0;
			song.muteGuitar(playerNumber);
		}
	}

	public void start() {
		song.start();
	}

	public void setSong(Song song) {
		this.song = song;

	}

	public void update() {
		// TODO Auto-generated method stub
		if (song != null)
			song.update();
	}
}
